package com.vichat.user.security;

import com.vichat.common.cache.RedisHelper;
import com.vichat.common.util.Configure;
import com.vichat.common.util.CookieUtil;
import com.vichat.common.util.JwtUtil;
import com.vichat.common.util.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * JwtFilter强制执行单点登录。如果JWT令牌不存在(未经验证)，则重定向到认证。 如果JWT令牌存在(已验证)，则提取用户标识并转发请求。
 */
@Component
public class JwtFilter extends OncePerRequestFilter {

	private String jwtTokenCookieName;
	private String signingKey;

	public JwtFilter() {
		this.jwtTokenCookieName = Configure.getString("jwt.token.cookie.name");
		this.signingKey = Configure.getString("signing.key");
	}

	@Override
	public void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
		boolean isPass = true;
		String token =httpServletRequest.getHeader("access_token");
        //System.out.println("header access_token:"+token);
        if(StringUtils.isBlank(token)){
            token =  httpServletRequest.getParameter("access_token");
            //System.out.println("request access_token:"+token);
        }
        if(StringUtils.isBlank(token)){
            token = CookieUtil.getValue(httpServletRequest, "access_token");
            //System.out.println("cookie access_token:"+token);
        }
        //System.out.println("final access_token:"+token);
		String uid = JwtUtil.getSubject(httpServletRequest, token, this.signingKey);//access_token解析出uid
		if (uid == null) {
			isPass = false;//uid为空则不通过
		} else {
			String jwtFRD = RedisHelper.get("LOGIN_TOKEN:" + uid);
			if (!StringUtils.equals(token, jwtFRD)) {
				isPass = false;//与redis不一致则不通过
			}
			String userJson = RedisHelper.getUser(NumberUtils.toLong(uid));
			if (StringUtils.isBlank(userJson)) {//uid在redis中无用户信息则不通过
				isPass = false;
			}
		}

		if (isPass) {
			httpServletRequest.setAttribute("uid", uid);
			filterChain.doFilter(httpServletRequest, httpServletResponse);
		} else {
			String noAuthUrl = getUrl(httpServletRequest)+"/vc/noAuth";
			httpServletResponse.sendRedirect(noAuthUrl);
		}
	}

	private String getUrl(HttpServletRequest request){
		String serverName = request.getServerName();
		int port = request.getServerPort();
		StringBuilder sbd = new StringBuilder();
		// 强制使用https
		sbd.append("http://").append(serverName);
		if(port != 80 ) {
			sbd.append(":").append(port).append("/");
		}
		return sbd.toString();
	}
}
